#ifndef DATA_TYPE_H_
#define DATA_TYPE_H_

#include <Eigen/Dense>
#include <mutex>
#include <shared_mutex>

#include "basic_settings.h"
#include "basic_type.h"
#include "fixed_array.h"
#include "point_cloud.h"

struct LidarData {
  ///@brief sensor name
  std::string name;
  ///@brief point cloud
  PointCloud<PointXYZIT, kMaxPointNum> point_cloud;
  ///@brief is valid
  bool is_valid;
};

struct CameraData {
  ///@brief sensor name
  std::string name;
  ///@brief image
  ImageData image_data;
  ///@brief is valid
  bool is_valid;
};

struct RadarData {
  ///@brief sensor name
  std::string name;
  ///@brief image
  PointCloud<PointXTZDopppler, kMaxPointNum> point_cloud;
  ///@brief is valid
  bool is_valid;
};

struct MatrixData {
  ///@brief name
  std::string name;
  ///@brief calibration matrix
  Eigen::MatrixXf mat;
  ///@brief is valid
  bool is_valid;
};

/// @brief lane mark line type
enum class LineType : int {
  /// @brief none
  None = -1,
  /// @brief dashed
  Dashed = 0,
  /// @brief solid
  Solid = 1,
};

struct alignas(8) LaneDividerLine {
  ///@brief id
  std::string id;
  ///@brief line type
  LineType type;
  /// @brief color
  std::string color;
  ///@brief position: x,y,z
  FixedArray<Point3f, kMaxMapLinePointsNum> points;
};

struct alignas(8) RoadEdgeLine {
  ///@brief id
  std::string id;
  ///@brief position: x,y,z
  FixedArray<Point3f, kMaxMapLinePointsNum> points;
};

struct alignas(8) RoadMarkingLine {
  ///@brief id
  std::string id;
  /// @brief category
  FixedArray<std::string, kMaxMapLinePointsNum> categorys;
  ///@brief position: x,y,z
  FixedArray<Point3f, kMaxMapLinePointsNum> polygons;
};

struct alignas(8) Map {
  /// @brief timestamp
  uint64_t timestamp;
  ///@brief Lane divider;
  FixedArray<LaneDividerLine, KMaxLaneMarkerLineNum> lane_divider;
  ///@brief road edge
  FixedArray<RoadEdgeLine, KMaxLaneMarkerLineNum> road_edge;
  ///@brief road marking;
  FixedArray<RoadMarkingLine, KMaxLaneMarkerLineNum> road_marking;
};

struct DataFrame {
  /// @brief timestamp
  uint64_t timestamp;
  ///@brief lidar data
  FixedArray<LidarData, kMaxLidarNum> lidar_data;
  ///@brief camera data
  FixedArray<CameraData, kMaxCameraNum> camera_data;
  ///@brief radar data
  FixedArray<RadarData, kMaxRadarNum> radar_data;
  ///@brief ego motion data
  MatrixData ego_data;
  /// @brief map annotation
  Map map_anno;
  /// @brief read write mutex
  mutable std::shared_mutex mutex;
};

struct DataBuf {  
  std::pair<char*, std::uint64_t> lidar_data;
  std::pair<char*, std::uint64_t> camera_data[5];
  std::pair<char*, std::uint64_t> pre_input;
  std::pair<char*, std::uint64_t> align_matrix;
  std::pair<char*, std::uint64_t> ring_matrix;
  std::pair<char*, std::uint64_t> ray_matrix;

  std::pair<char*, std::uint64_t> kCat2491;
  std::pair<char*, std::uint64_t> kCat2492;
  std::pair<char*, std::uint64_t> k2647;
};

#endif  // !DATA_TYPE_H_
